package com.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * 自定义权限过滤器
 * 用于验证请求中的Token
 */
@Component
@Slf4j
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {

    private static final String TOKEN_PREFIX = "Bearer ";
    // 白名单路径，不需要验证Token
    private static final List<String> WHITE_LIST = Arrays.asList(
            "/api/auth/login",
            "/api/auth/register",
            "/api/huodongbaoming/public",
            "/static/"
    );

    public AuthFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();

            // 检查是否是白名单路径
            if (isWhitePath(path)) {
                return chain.filter(exchange);
            }

            // 获取Token
            String token = getToken(request);
            if (!StringUtils.hasText(token)) {
                return unauthorized(exchange.getResponse(), "未提供有效的Token");
            }

            // 验证Token (实际项目中应该调用认证服务进行验证)
            boolean isValid = validateToken(token);
            if (!isValid) {
                return unauthorized(exchange.getResponse(), "Token无效或已过期");
            }

            // Token验证通过，继续处理请求
            log.info("Token验证通过，用户请求：{}", path);
            
            // 将用户信息传递给下游服务
            ServerHttpRequest newRequest = request.mutate()
                .header("X-User-Id", getUserIdFromToken(token))
                .build();
            
            return chain.filter(exchange.mutate().request(newRequest).build());
        };
    }

    /**
     * 检查是否是白名单路径
     */
    private boolean isWhitePath(String path) {
        return WHITE_LIST.stream().anyMatch(path::startsWith);
    }

    /**
     * 从请求头中获取Token
     */
    private String getToken(ServerHttpRequest request) {
        String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        if (StringUtils.hasText(authHeader) && authHeader.startsWith(TOKEN_PREFIX)) {
            return authHeader.substring(TOKEN_PREFIX.length());
        }
        return null;
    }

    /**
     * 验证Token
     * 实际项目中应该调用认证服务进行验证
     */
    private boolean validateToken(String token) {
        // 这里简单实现，实际项目中应该调用认证服务验证Token
        // 可以使用JWT等技术进行验证
        return StringUtils.hasText(token) && token.length() > 10;
    }
    
    /**
     * 从Token中获取用户ID
     * 实际项目中应该解析JWT Token
     */
    private String getUserIdFromToken(String token) {
        // 这里简单实现，实际项目中应该解析JWT Token
        return "user-" + token.substring(0, 5);
    }

    /**
     * 返回未授权响应
     */
    private Mono<Void> unauthorized(ServerHttpResponse response, String message) {
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8");
        
        String body = "{\"code\":401,\"message\":\"" + message + "\"}";
        DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
        
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 配置类
     */
    public static class Config {
        // 可以添加配置参数
    }
} 